/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * JCorrelationGraphView.java
 *
 * Created on 2010-5-26, 21:45:35
 */

package cn.ekuma.epos.analysis.businesspartner;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.MouseEvent;
import prefuse.Constants;
import prefuse.Display;
import prefuse.Visualization;
import prefuse.action.ActionList;
import prefuse.action.RepaintAction;
import prefuse.action.assignment.ColorAction;
import prefuse.action.layout.graph.ForceDirectedLayout;
import prefuse.activity.Activity;
import prefuse.controls.DragControl;
import prefuse.controls.FocusControl;
import prefuse.controls.NeighborHighlightControl;
import prefuse.controls.PanControl;
import prefuse.controls.WheelZoomControl;
import prefuse.controls.ZoomControl;
import prefuse.controls.ZoomToFitControl;
import prefuse.data.Graph;
import prefuse.data.Tuple;
import prefuse.data.event.TupleSetListener;
import prefuse.data.tuple.TupleSet;
import prefuse.render.DefaultRendererFactory;
import prefuse.render.LabelRenderer;
import prefuse.render.Renderer;
import prefuse.util.ColorLib;
import prefuse.visual.VisualGraph;
import prefuse.visual.VisualItem;

/**
 *
 * @author Administrator
 */
public class JCorrelationGraphView extends javax.swing.JPanel {
    private static final String graph = "graph";
    private static final String nodes = "graph.nodes";
    private static final String edges = "graph.edges";

    private Visualization m_vis;
    AnalysisModelManager manager;
    /** Creates new form JCorrelationGraphView */
    public JCorrelationGraphView(AnalysisModelManager manager) {
        initComponents();
        this.manager=manager;
          // create a new, empty visualization for our data
        m_vis = new Visualization();

         // --------------------------------------------------------------------
        // set up the renderers
        LabelRenderer tr = new LabelRenderer(AnalysisModelManager.LABEL);
        tr.setRoundedCorner(8, 8);
        m_vis.setRendererFactory(new ExtRendererFactory(tr));

        //fix selected focus nodes
        TupleSet focusGroup = m_vis.getGroup(Visualization.FOCUS_ITEMS);
        focusGroup.addTupleSetListener(new TupleSetListener() {
            public void tupleSetChanged(TupleSet ts, Tuple[] add, Tuple[] rem)
            {
                for ( int i=0; i<rem.length; ++i ){
                    ((VisualItem)rem[i]).setFixed(false);
                }
                for ( int i=0; i<add.length; ++i ) {
                    ((VisualItem)add[i]).setFixed(false);
                    ((VisualItem)add[i]).setFixed(true);
                }
                if ( ts.getTupleCount() == 0 ) {
                    ts.addTuple(rem[0]);
                    ((VisualItem)rem[0]).setFixed(false);
                }
                m_vis.run("draw");
            }
        });

        ColorAction fill = new ColorAction(nodes,
                VisualItem.FILLCOLOR, ColorLib.rgba(200,200,200,100));
        fill.add(VisualItem.FIXED, ColorLib.rgba(255,235,20,100));
        fill.add(VisualItem.HIGHLIGHT, ColorLib.rgba(160,160,0,120));

        ActionList draw = new ActionList();
        draw.add(fill);
        draw.add(new ColorAction(nodes, VisualItem.STROKECOLOR, 0));
        draw.add(new ColorAction(nodes, VisualItem.TEXTCOLOR, ColorLib.rgb(0,0,0)));
        draw.add(new ColorAction(edges, VisualItem.FILLCOLOR, ColorLib.gray(200)));
        draw.add(new ColorAction(edges, VisualItem.STROKECOLOR, ColorLib.gray(200)));

        ActionList animate = new ActionList(Activity.INFINITY);
        animate.add(new ForceDirectedLayout(graph));
        animate.add(fill);
        animate.add(new RepaintAction());

        // finally, we register our ActionList with the Visualization.
        // we can later execute our Actions by invoking a method on our
        // Visualization, using the name we've chosen below.
        m_vis.putAction("draw", draw);
        m_vis.putAction("layout", animate);
        m_vis.runAfter("draw", "layout");
         // --------------------------------------------------------------------
        // set up a display to show the visualization

        Display display = new Display(m_vis);
        display.setSize(500,400);
        display.pan(350, 350);
        // main display controls
        display.addControlListener(new AdvFocusControl(1));
        display.addControlListener(new DragControl());
        display.addControlListener(new PanControl());
        display.addControlListener(new ZoomControl());
        display.addControlListener(new WheelZoomControl());
        display.addControlListener(new ZoomToFitControl());
        display.addControlListener(new NeighborHighlightControl());

        display.setForeground(Color.GRAY);
        display.setBackground(Color.WHITE);
        m_vis.run("draw");
        display.setHighQuality(true);
        add(display, BorderLayout.CENTER);
    }

    public void setGraph(Graph g) {
        // update graph
        m_vis.removeGroup(graph);
        VisualGraph vg = m_vis.addGraph(graph, g);
        //m_vis.setValue(edges, null, VisualItem.INTERACTIVE, Boolean.FALSE);
        if(g.getNodeCount()>0){
            VisualItem f = (VisualItem)vg.getNode(0);
            m_vis.getGroup(Visualization.FOCUS_ITEMS).setTuple(f);
            f.setFixed(false);
        }
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        setLayout(new java.awt.BorderLayout());
    }// </editor-fold>//GEN-END:initComponents


    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables


    class AdvFocusControl extends FocusControl{
        public AdvFocusControl(int count){
            super(count);
        }
        
        @Override
        public void itemEntered(VisualItem item, MouseEvent e) {
            if(item.canGetString(AnalysisModelManager.TYPE)){
                 item.set(AnalysisModelManager.TYPE,AnalysisModelManager.DETAILS);
            }
            super.itemEntered(item, e);
        }

        @Override
        public void itemExited(VisualItem item, MouseEvent e) {
            if(item.canGetString(AnalysisModelManager.TYPE)){
               item.set(AnalysisModelManager.TYPE,AnalysisModelManager.LABEL);
            }
            super.itemExited(item, e);
        }

        @Override
        public void itemClicked(VisualItem item, MouseEvent e) {
            super.itemClicked(item, e);
            if(item.canGetString(AnalysisModelManager.ORDERID))
                manager.fireOrderChanged(this,item.getString(AnalysisModelManager.ORDERID));
        }
    }

    class ExtRendererFactory extends DefaultRendererFactory{
        private LabelRenderer dRenderer;

        private ExtRendererFactory(LabelRenderer tr) {
            super(tr);
            dRenderer=new LabelRenderer(AnalysisModelManager.DETAILS);
            dRenderer.setRoundedCorner(8, 8);
            dRenderer.setHorizontalTextAlignment(Constants.LEFT);
        }
        
        @Override
        public Renderer getRenderer(VisualItem item) {
            if(item.canGetString(AnalysisModelManager.TYPE)){
                 String dtype=(String) item.get(AnalysisModelManager.TYPE);
                 if(dtype!=null&&dtype.equalsIgnoreCase(AnalysisModelManager.DETAILS))
                   return dRenderer;
            }
            return super.getRenderer(item);
        }
    }
}
